interface IconFontConfig {
  scriptUrl: string; // iconfont 的 Font class 地址
}

class IconFontLoader {
  private static instance: IconFontLoader;

  private loadedUrls: Set<string> = new Set();

  private iconList: string[] = [];

  public static getInstance(): IconFontLoader {
    if (!IconFontLoader.instance) {
      IconFontLoader.instance = new IconFontLoader();
    }
    return IconFontLoader.instance;
  }

  /**
   * 加载 iconfont 脚本
   * @param config 配置项
   */
  public async load(config: IconFontConfig): Promise<void> {
    const { scriptUrl } = config;

    if (this.loadedUrls.has(scriptUrl)) {
      return;
    }

    await new Promise<void>((resolve, reject) => {
      const link = document.createElement('link');
      link.rel = 'stylesheet'; // 设置为样式表
      link.href = scriptUrl; // 使用 href 属性引入

      link.onload = () => {
        this.loadedUrls.add(scriptUrl);
        this.updateIconList();
        resolve();
      };

      link.onerror = () => {
        reject(new Error(`Failed to load iconfont link: ${scriptUrl}`));
      };

      document.head.appendChild(link); // 将 link 标签添加到 head 中
    });
  }

  /**
   * 更新图标列表
   */
  private updateIconList(): void {
    const iconElements = document.querySelectorAll('symbol');
    this.iconList = Array.from(iconElements).map((el) => el.id);
  }

  /**
   * 获取所有已加载的图标名称列表
   * @returns string[]
   */
  public getIconList(): string[] {
    return [...this.iconList];
  }
}

// 导出单例实例
export const iconLoader = IconFontLoader.getInstance();

// 导出加载方法
export const loadIconfont = (config: IconFontConfig) => {
  return iconLoader.load(config);
};

// 导出获取图标列表方法
export const getIconList = () => {
  return iconLoader.getIconList();
};
